﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;

namespace Project
{
    public class SpikeBall : GameEntity, Renderable
    {
        protected Model model;
        protected Effect modelEffect;
        protected PointLight light;

        private Vector3 startPosition;
        private const float MAX_DISTANCE_SQ = 10000;

        public SpikeBall(Vector3 position, Vector3 direction) : base(position)
        {
            this.health = 1;

            // don't smooth out rotation
            slerpConstant = 0.09f;

            startPosition = position;

            // bouncin'
            elasticity = 1.0f;
            gravity = Vector3.Zero;
            dragConstant = 0;
            frictionConstant = 0;
            // set initial velocity
            velocity = direction;
            velocity.Normalize();
            velocity *= 10.0f;

            light = new PointLight(-position, new Color(1, 0.25f, 0.05f, 1), 0.5f, 0.1f, 0.1f);

            collisionObject = new CollisionObject(
                new AABB(new Vector3(-0.2f, -0.2f, -0.2f), new Vector3(0.2f, 0.2f, 0.2f), -position),
                delegate(CollisionData data)
                {
                    // damage the player
                    if (data.entity != null && data.entity is Player)
                    {
                        data.entity.damage(100);
                    }
                    // destruct on impact with anything
                    this.kill();
                }, this
            );
        }

        public override void init(GameState gs)
        {
            base.init(gs);
            modelEffect = gs.loadAsset<Effect>("effects\\item");
            model = gs.loadAsset<Model>("models\\spiky_ball_low_res");
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    part.Effect = modelEffect;
                }
            }
            gs.getScene().renderables.Add(this);

            gs.getScene().pointLights.Add(light);
        }

        public override void destroy(GameState gs)
        {
            base.destroy(gs);
            gs.getScene().renderables.Remove(this);
            gs.getScene().pointLights.Remove(light);
        }

        public override bool update(GameTime gt, GameState gs)
        {
            if ((position - startPosition).LengthSquared() > MAX_DISTANCE_SQ)
            {
                kill();
            }

            if (health < 0)
            {
                return false;
            }

            light.position = -position;

            return base.update(gt, gs);
        }

        public void render(GameTime gt, Camera camera)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            Matrix worldMatrix = Matrix.CreateTranslation(-position);
            model.CopyAbsoluteBoneTransformsTo(transforms);
            modelEffect.Parameters["World"].SetValue(worldMatrix);
            modelEffect.Parameters["WVP"].SetValue(worldMatrix * camera.view * camera.projection);
            modelEffect.Parameters["Color"].SetValue(new Vector4(1, 0.25f, 0.05f, 1));
            foreach (ModelMesh mesh in model.Meshes)
            {
                mesh.Draw();
            }
        }

        public void kill()
        {
            health = -1;
        }

    }
}
